package com.steel.yfmall.cloud.assistant.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.steel.yfmall.cloud.assistant.bean.AssistantConstants;
import com.steel.yfmall.cloud.assistant.dto.zg.product.ZgStockBean;
import com.steel.yfmall.cloud.assistant.dto.zg.product.ZgStockResultCodeBean;
import com.steel.yfmall.cloud.assistant.dto.zg.result.ZgGoodsTemplateBean;
import com.steel.yfmall.cloud.assistant.goods.ProductPriceFormFactorService;
import com.steel.yfmall.cloud.assistant.goods.ProductPriceFormService;
import com.steel.yfmall.cloud.assistant.goods.ProductSellerGoodsService;
import com.steel.yfmall.cloud.assistant.dto.para.goods.ParaProductPriceFormBean;
import com.steel.yfmall.cloud.assistant.dto.para.goods.ParaProductPriceFormFactorDatailsBean;
import com.steel.yfmall.cloud.assistant.dto.para.goods.ParaProductSellerGoodsBean;
import com.steel.yfmall.cloud.assistant.dto.result.goods.ResultProductPriceAttribute;
import com.steel.yfmall.cloud.assistant.dto.result.goods.ResultProductPriceFormFactorDatailsBean;
import com.steel.yfmall.cloud.assistant.dto.result.goods.ResultProductSellerGoodsBean;
import com.steel.yfmall.cloud.assistant.dto.zg.price.Sr051voBean;
import com.steel.yfmall.cloud.assistant.dto.zg.price.Sr062Bean;
import com.steel.yfmall.cloud.assistant.dto.zg.price.Sr063Bean;
import com.steel.yfmall.cloud.assistant.po.goods.SteelProductPriceBean;
import com.steel.yfmall.cloud.assistant.po.goods.SteelProductPriceFormBean;
import com.steel.yfmall.cloud.assistant.utils.HttpSendUtil;
import com.steel.yfmall.cloud.assistant.view.GoodsTemplateService;
import com.steel.yfmall.cloud.components.mq.bean.RequestSendMQBean;
import com.steel.yfmall.cloud.components.mq.service.MqSendService;
import com.steel.yfmall.cloud.components.utils.utils.PriceUtils;
import com.steel.yfmall.cloud.product.bean.response.APIResultPriceInfoBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class ProductPriceListener {

    @Resource
    private ProductPriceFormService productPriceFormService;

    @Resource
    private ProductPriceFormFactorService productPriceFormFactorService;

    @Resource
    private ProductSellerGoodsService productSellerGoodsService;

    @Resource
    private MqSendService mqSendService;

    /**
     * 同步价格后刷新商品基础价格
     *
     * @return void    返回类型
     * @Title: RefreshProductTypePriceListenerOnMessage
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param onMsgText 参数说明
     * @author yuchaohua
     * @date 2020/12/8 15:17
     */
    @JmsListener(destination = "refresh_product_type_price")
    public void RefreshProductTypePriceListenerOnMessage(String onMsgText) {
        try {
            if (log.isDebugEnabled()) {
                log.info("refresh_product_type_price" + onMsgText);
            }
            if (StringUtils.isBlank(onMsgText)) {
                log.error("同步价格后刷新商品基础价格:参数为空");
                return;
            }
            Sr051voBean sr051voBean = JSON.parseObject(onMsgText, Sr051voBean.class);
            if (sr051voBean == null || StringUtils.isBlank(sr051voBean.getPriceClassify()) || StringUtils.isBlank(sr051voBean.getPriceType())) {
                log.error("同步价格后刷新商品基础价格:参数为空");
                return;
            }
            updatePrice(sr051voBean);
        } catch (Exception e) {
            log.error(onMsgText + "同步价格后刷新商品基础价格失败", e);
        }
    }


    public String updatePrice(Sr051voBean sr051voBean) {
        //查询商品价格信息
        SteelProductPriceBean paraSteelProductPriceBean = new SteelProductPriceBean();
        paraSteelProductPriceBean.setPriceType(sr051voBean.getPriceType());
        paraSteelProductPriceBean.setPriceClassify(sr051voBean.getPriceClassify());
        paraSteelProductPriceBean.setStatus(1);
        SteelProductPriceBean dbResultSteelProductPriceInfo = productPriceFormService.getSteelProductPriceBeanByPara(paraSteelProductPriceBean);
        if (dbResultSteelProductPriceInfo == null) {
            log.error("商品价格信息不存在!");
            return "商品价格信息不存在!";
        }
        //查询价格组成
        ParaProductPriceFormBean paraSteelProductPriceFormBean = new ParaProductPriceFormBean();
        paraSteelProductPriceFormBean.setPriceType(sr051voBean.getPriceType());
        paraSteelProductPriceFormBean.setPriceClassify(sr051voBean.getPriceClassify());
        paraSteelProductPriceFormBean.setStatus(1);
        List<SteelProductPriceFormBean> dbResultPriceFormInfoList = productPriceFormFactorService.getSteelProductPriceFormBeanByPara(paraSteelProductPriceFormBean);
        if (dbResultPriceFormInfoList == null || dbResultPriceFormInfoList.size() <= 0) {
            log.error("商品价格组信息不存在!");
            return "商品价格组信息不存在!";
        }
        //捞取所有价格组成id
        List<Integer> priceFormIdList = new ArrayList<>();
        //存放价格组成  价格描述信息  封装返回价格信息描述信息使用
        Map<Integer, List<Sr062Bean>> productPriceFormFactorMap = new HashMap<>();
        //价格组成描述
        Map<Integer, String> priceFormDescMap = new HashMap<>();
        for (SteelProductPriceFormBean priceFormBean : dbResultPriceFormInfoList) {
            priceFormIdList.add(priceFormBean.getId());
            //价格组成描述
            priceFormDescMap.put(priceFormBean.getId(), priceFormBean.getPriceName());
            if (StringUtils.isNotBlank(priceFormBean.getProductPriceFormFactor())) {
                List<Sr062Bean> productPriceFormFactorList = null;
                try {
                    productPriceFormFactorList = JSONArray.parseArray(priceFormBean.getProductPriceFormFactor(), Sr062Bean.class);
                } catch (Exception e) {
                    log.error("价格组因子描述信息转换失败:" + JSON.toJSONString(priceFormBean.getProductPriceFormFactor()));
                }
                if (productPriceFormFactorList != null && productPriceFormFactorList.size() > 0) {
                    productPriceFormFactorMap.put(priceFormBean.getId(), productPriceFormFactorList);
                }
            }
        }

        ParaProductPriceFormFactorDatailsBean paraFactorDetailBean = new ParaProductPriceFormFactorDatailsBean();
        paraFactorDetailBean.setProductPriceFormIdList(priceFormIdList);
        Map<Integer, List<ResultProductPriceFormFactorDatailsBean>> resultPriceFactorDetailMap = productPriceFormFactorService.getSteelProductPriceFormFactorDetailsBeanMap(paraFactorDetailBean);
        if (resultPriceFactorDetailMap == null || resultPriceFactorDetailMap.isEmpty()) {
            log.error("商品价格组成因子信息不存在！");
            return "商品价格组成因子信息不存在！";
        }

        ParaProductSellerGoodsBean paraSellerGoodsBean = new ParaProductSellerGoodsBean();
        //paraSellerGoodsBean.setProductTypeNo(sr051voBean.getPriceType());
        paraSellerGoodsBean.setProdClass(sr051voBean.getPriceType());
        paraSellerGoodsBean.setOrderByValue("product_sys_code asc");
        int sellerGoodsCount = (int) productSellerGoodsService.countSellerGoodsListBySite(paraSellerGoodsBean);
        if (sellerGoodsCount <= 0) {
            log.error("暂时没有需要发送降价通知的收藏记录" + JSON.toJSONString(sr051voBean));
            return "暂时没有需要发送降价通知的收藏记录";
        }
        // 分批次数
        int timesQty = sellerGoodsCount % AssistantConstants.DO_BATCH_NO > 0 ? sellerGoodsCount / AssistantConstants.DO_BATCH_NO + 1 : sellerGoodsCount / AssistantConstants.DO_BATCH_NO;
        paraSellerGoodsBean.setLength(AssistantConstants.DO_BATCH_NO);
        for (int i = 0; i < timesQty; i++) {
            // 起始位置
            paraSellerGoodsBean.setStart(i * AssistantConstants.DO_BATCH_NO);
            List<ResultProductSellerGoodsBean> sellerGoodsBeans = productSellerGoodsService.getSellerGoodsListBySite(paraSellerGoodsBean);
            if (!CollectionUtils.isEmpty(sellerGoodsBeans)) {

                Map<Double,List<String>> priceGoodListMap = new HashMap<>();
                // 发送消息改价
                for (ResultProductSellerGoodsBean resultProductInfo : sellerGoodsBeans) {
                    // 计算后的商品价格
                    double goodsPrice = 0.00d;
                    // 计算
                    List<APIResultPriceInfoBean.PriceForm> priceFormList = new ArrayList<>();
                    //转换商品相关需要计算价格属性
                    ResultProductPriceAttribute resultProductPriceAttribute = copyProductPriceAttribute(resultProductInfo);
                    //循环价格组信息  进行匹配价格因子 进行匹配价格
                    for (Integer priceFormId : priceFormIdList) {
                        //如果该价格因子为空  那么直接跳过该价格组下的价格因子的匹配
                        if (!resultPriceFactorDetailMap.containsKey(priceFormId) || CollectionUtils.isEmpty(resultPriceFactorDetailMap.get(priceFormId))) {
                            continue;
                        }
                        APIResultPriceInfoBean.PriceForm priceForm = hitProductPriceFromPriceFactor(priceFormId, productPriceFormFactorMap.get(priceFormId), priceFormDescMap, resultProductPriceAttribute, resultPriceFactorDetailMap.get(priceFormId));
                        if (priceForm != null) {
                            priceFormList.add(priceForm);
                            goodsPrice = PriceUtils.add(goodsPrice, priceForm.getFormPrice());
                        }
                    }
                    // 修改商品价格信息
                    if (CollectionUtils.isNotEmpty(priceFormList) && goodsPrice > 0) {
                        if(priceGoodListMap.containsKey(goodsPrice)){
                            priceGoodListMap.get(goodsPrice).add(resultProductInfo.getProductSysCode());
                        }else{
                            List<String> productList = new ArrayList<>();
                            productList.add(resultProductInfo.getProductSysCode());
                            priceGoodListMap.put(goodsPrice,productList);
                        }
                    }
                }
                if (priceGoodListMap != null && priceGoodListMap.size() > 0){
                    // 批量修改价格信息
                    for(Map.Entry<Double,List<String>> productList : priceGoodListMap.entrySet()){
                        ParaProductSellerGoodsBean sellerGoodsBean = new ParaProductSellerGoodsBean();
                        sellerGoodsBean.setProductSysCodeList(productList.getValue());
                        // 价格
                        sellerGoodsBean.setMarketPrice(PriceUtils.mulBigDecimal(productList.getKey(), 1));
                        RequestSendMQBean requestSendMQBean = new RequestSendMQBean();
                        requestSendMQBean.setSendMqTitle("template_update_product_price");
                        requestSendMQBean.setSendMqMessage(JSON.toJSONString(sellerGoodsBean));
                        mqSendService.sendCommonMQMessage(requestSendMQBean);
                    }
                }
            }
        }
        return null;
    }

    /**
     * copy需要计算商品价格属性  到价格属性bean
     *
     * @param dbResultProductInfo
     * @return
     */
    public ResultProductPriceAttribute copyProductPriceAttribute(ResultProductSellerGoodsBean dbResultProductInfo) {
        //定制商品  长宽厚  前端参数传入 优先获取
        ResultProductPriceAttribute resultProductPriceAttribute = new ResultProductPriceAttribute();
        resultProductPriceAttribute.setTradeTermRemark(dbResultProductInfo.getDepotCode());
        resultProductPriceAttribute.setProdType(dbResultProductInfo.getProductTypeNo());
        resultProductPriceAttribute.setOrderLength(dbResultProductInfo.getProductLen().doubleValue());
        resultProductPriceAttribute.setOrderThick(dbResultProductInfo.getProductThick().doubleValue());
        resultProductPriceAttribute.setSpecialCase(dbResultProductInfo.getCraft());
        resultProductPriceAttribute.setProdSpecNo(dbResultProductInfo.getProductTradeno());
        return resultProductPriceAttribute;
    }


    /**
     * 循环命中价格
     *
     * @param priceFormId
     * @param Sr062BeanList
     * @param priceFormDescMap
     * @param resultProductPriceAttribute
     * @param SteelProductPriceFormFactorDatailsBeanList
     * @return
     */
    public APIResultPriceInfoBean.PriceForm hitProductPriceFromPriceFactor(int priceFormId, List<Sr062Bean> Sr062BeanList, Map<Integer, String> priceFormDescMap,
                                                                           ResultProductPriceAttribute resultProductPriceAttribute, List<ResultProductPriceFormFactorDatailsBean> SteelProductPriceFormFactorDatailsBeanList) {
        APIResultPriceInfoBean.PriceForm priceForm = null;
        //循环价格因子
        BeanMap beanMap = BeanMap.create(resultProductPriceAttribute);
        for (ResultProductPriceFormFactorDatailsBean factorDatailsBean : SteelProductPriceFormFactorDatailsBeanList) {
            Map<String, Sr063Bean> priceFactorMap = factorDatailsBean.getProductPriceFormFactorDetailMap();
            if (priceFactorMap == null) {
                log.error("价格因子数据异常，价格组信息为：" + priceFormId);
                return priceForm;
            }

            //该价格因子组数量  用于校验是否匹配上该价格
            int checkPriceSucessCount = factorDatailsBean.getProductPriceFormFactorDetailList().size();
            //记录次数
            int priceSucessCount = 0;
            for (String key : priceFactorMap.keySet()) {
                //价格因子存在价格代码  商品中没有值
                if (!beanMap.containsKey(key)) {
                    continue;
                }
                //取出该条价格因子
                Sr063Bean sr063Bean = priceFactorMap.get(key);
                try {
                    //判断该条因子值 是否为空
                    if(StringUtils.isNotBlank(sr063Bean.getFacVal())){
                        if(!StringUtils.equalsIgnoreCase((String)beanMap.get(key),sr063Bean.getFacVal())){
                            continue;
                        }
                    }else{
                        //当该条因子所有属性值都为空时  代表忽略该因子的匹配
                        if(StringUtils.isBlank(sr063Bean.getFatValueMin()) && StringUtils.isBlank(sr063Bean.getFatValueMax())){
                            priceSucessCount++;
                            continue;
                        }
                        //此时判断范围值  此时商品该属性值一定为数字类型
                        if(NumberUtils.toDouble(String.valueOf(beanMap.get(key))) < NumberUtils.toDouble(sr063Bean.getFatValueMin())
                                || NumberUtils.toDouble(String.valueOf(beanMap.get(key))) > NumberUtils.toDouble(sr063Bean.getFatValueMax())){
                            continue;
                        }
                    }
                    priceSucessCount++;
                }catch (Exception e){
                    log.error("价格匹配出现错误：" + JSON.toJSONString(beanMap), e);
                    log.error("价格匹配出现错误 key : " + key);
                    log.error("价格匹配出现错误 参照物:" + JSON.toJSONString(sr063Bean), e);
                }
            }
            //此时代表价格因子全部命中
            if (checkPriceSucessCount == priceSucessCount) {
                priceForm = new APIResultPriceInfoBean.PriceForm();
                //此时取该价格  并且进行封装价格描述
                priceForm.setFormPrice(factorDatailsBean.getPrice().doubleValue());
                StringBuffer priceDesc = new StringBuffer();
                priceDesc.append(priceFormDescMap.get(priceFormId) + "=");
                for (Sr062Bean Sr062Bean : Sr062BeanList) {
                    priceDesc.append(Sr062Bean.getFactorDesc() + "+");
                }
                priceDesc.deleteCharAt(priceDesc.length() - 1);
                priceForm.setPriceFormDescribe(priceDesc.toString());
                return priceForm;
            }
        }
        return priceForm;
    }


    /**
     * 根据条件同步erp库存
     *
     * @return void    返回类型
     * @Title: SynchronizeErpStockListenerOnMessage
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param onMsgText 参数说明
     * @author yaokan
     * @date 2020/12/8 15:17
     */
    @JmsListener(destination = "synchronize_erp_stock")
    public void SynchronizeErpStockListenerOnMessage(String onMsgText) {
        try {
            if (log.isDebugEnabled()) {
                log.info("synchronize_erp_stock" + onMsgText);
            }
            if (StringUtils.isBlank(onMsgText)) {
                log.error("同步erp库存:参数为空");
                return;
            }
            Object parse = JSON.parse(onMsgText);
            ZgStockBean zgStockBean = JSON.parseObject(parse.toString(), ZgStockBean.class);
            if (zgStockBean == null || StringUtils.isBlank(zgStockBean.getBrandCode()) || StringUtils.isBlank(zgStockBean.getProdClass())) {
                log.error("同步库存失败:参数为空");
                return;
            }
            synchronizeErpStock(zgStockBean);
        } catch (Exception e) {
            log.error(onMsgText + "同步价格后刷新商品基础价格失败", e);
        }
    }

    /**
     * 查询erp库存
     *
     * @param
     * @return
     * @author yaokan
     * @date 2021-03-24 10:43
     *
     * 2接口方式与格式定义
     * 接口提供者：ERP
     * 接口调用者：电商平台
     * 接口协议：http协议，使用Web服务的方式进行数据传递
     * 传送数据格式：JSON
     *
     *输入参数：
     * 厂区	brandId	字符		必传,永锋：YF;永锋临港：LG；永锋科技：KJ等
     * 产品大类	prodClass	字符		必传， H-钢材 F-副产品 K-矿产品 S-溶剂产品
     * Z-其它
     * M-模铸
     * B-钢坯
     * C-科技砖类
     *
     * 输出参数：
     * 字段名称	类型	说明
     * brandId	string	厂区编码
     * stockId	string	仓库编码
     * prodClass	string	产品大类编码
     * prodTypeNo	string	产品形态编码
     * tradeno	string	钢种/牌号
     * grade	string	商品品级：1为正品，2为次级品，3为协议品，4为好品浮锈，5为好品生锈，6为好品重度锈蚀，7为次品浮锈，8为次品生锈，9为次品重度锈蚀，A为判废
     * sizePieces	integer	大小件：0为小件，1为大件
     * sizeMsg	string	尺寸信息：N为棒材定尺，S为棒材非定尺，W为线材定尺，X为线材非尺
     * craft	integer	工艺：1为穿水，2为轻穿水，3为热轧，5为铁标，6为控冷，7为实验
     * isDowngrade	string	是否降级：N为否，Y为是
     * prodThick	decimal	直径
     * prodLen	decimal	长度
     * prodWidth	decimal	宽度
     * color	string	颜色名称
     * canUseQty	int	可用件数
     * canUseWgt	decimal	可用重量
     * transWayNo 运输方式  R火车  T汽车
     */
    public void  synchronizeErpStock(ZgStockBean zgStockBean){
        if (zgStockBean == null) {
            return;
        }
        String brandCode = zgStockBean.getBrandCode();
        String prodClass = zgStockBean.getProdClass();

        ///http://192.168.60.96/erp/sb/ajax?_controller=sbjcApiForEC&_action=S&brandId=YF&prodClass=H
        String abc = "_controller=sbjcApiForEC&_action=S&brandId=" + brandCode + "&prodClass=" + prodClass;
        String result = HttpSendUtil.sendPost(YF_ERP_STOCK_URL, abc, "");

        log.info("同步erp库存信息url:" + YF_ERP_STOCK_URL + ",参数:" + abc + ",result:" + result);
        ZgStockResultCodeBean zgStockBeanResult = JSON.parseObject(result, ZgStockResultCodeBean.class);
        if (zgStockBeanResult.getRtnCode() != 200) {
            log.info("同步erp库存信息失败 ，url:" + YF_ERP_STOCK_URL + ",参数:" + abc + ",result:" + result);
            return;
        }
        List<ZgStockBean> stockList = zgStockBeanResult.getStockList();

        List<ZgStockBean> zgStockBeanList = new ArrayList<>();
        for (ZgStockBean stockBean : stockList) {
            ZgGoodsTemplateBean paraBean  = new ZgGoodsTemplateBean();
            paraBean.setBrandId(stockBean.getBrandId());
            paraBean.setProdClass(stockBean.getProdClass());
            paraBean.setProdTypeNo(stockBean.getProdTypeNo());
            paraBean.setTradeNo(stockBean.getTradeno());
            paraBean.setStockId(stockBean.getStockId());
            paraBean.setProdThick(stockBean.getProdThick());
            paraBean.setProdWidth(stockBean.getProdWidth());
            paraBean.setProdLen(stockBean.getProdLen());
            paraBean.setSizeMsg(stockBean.getSizeMsg());
            paraBean.setGrade(stockBean.getGrade());
            paraBean.setCountWgtMode(stockBean.getCountWgtMode());
            paraBean.setSizePieces(stockBean.getSizePieces());
            paraBean.setCraft(stockBean.getCraft());
            paraBean.setIsDowngrade(stockBean.getIsDowngrade());
            paraBean.setColor(stockBean.getColor());
            paraBean.setTransWayNo(stockBean.getTransWayNo());
            String md5 = goodsTemplateService.goodsIndexMd5(paraBean);

            stockBean.setAttrEncryption(md5);
            zgStockBeanList.add(stockBean);
        }

        //发送渠道商城库存mq
        RequestSendMQBean requestSendMQBean = new RequestSendMQBean();
        requestSendMQBean.setSendMqTitle("produc_stock_sync_update_listener");
        requestSendMQBean.setSendMqMessage(JSON.toJSONString(zgStockBeanList));
        mqSendService.sendCommonMQMessage(requestSendMQBean);
    }

    @Value("${yf_erp_stock_url}")
    private String YF_ERP_STOCK_URL;

    @Resource
    private GoodsTemplateService goodsTemplateService;



}
